/*
 * ISourceBuilder.cpp
 *
 *  Created on: 26 juin 2011
 *      Author: Pierrick Caillon <pierrick@megami.fr>
 */

#include "SourceBuilder.h"

class SourceEntry
{
private:
	SourceBuilder::instantiateFunction constructor;
	SourceBuilder::validityFunction check;
	SourceEntry* next;
	SourceEntry(SourceBuilder::instantiateFunction constructor,
			SourceBuilder::validityFunction check);
public:
	SourceEntry();
	~SourceEntry();
	void AppendEntry(SourceBuilder::instantiateFunction constructor,
			SourceBuilder::validityFunction check);
	ISource *Create();
	bool is_Valid();
	SourceEntry *get_Next();
};
SourceEntry headSB;

SourceBuilder::SourceBuilder()
{
}

SourceBuilder::~SourceBuilder()
{
}

SourceEntry::~SourceEntry()
{
	if (this->next != NULL)
		delete this->next;
}

void SourceBuilder::RegisterBuilder(instantiateFunction constructor,
		validityFunction check)
{
	headSB.AppendEntry(constructor, check);
}

ISource *SourceBuilder::get_FirstSource()
{
	SourceEntry *entry = headSB.get_Next();
	while (entry != NULL)
	{
		if (entry->is_Valid())
			return entry->Create();
		entry = entry->get_Next();
	}
	return NULL;
}

SourceEntry::SourceEntry(SourceBuilder::instantiateFunction constructor,
		SourceBuilder::validityFunction check)
{
	this->constructor = constructor;
	this->check = check;
	this->next = NULL;
}

SourceEntry::SourceEntry()
{
	this->constructor = NULL;
	this->check = NULL;
	this->next = NULL;
}

bool SourceEntry::is_Valid()
{
	if (this->check != NULL)
		return (this->check)();
	return false;
}

SourceEntry *SourceEntry::get_Next()
{
	return this->next;
}

void SourceEntry::AppendEntry(SourceBuilder::instantiateFunction constructor,
		SourceBuilder::validityFunction check)
{
	SourceEntry *last = this;
	SourceEntry *current = this->next;
	while (current != NULL)
	{
		last = current;
		current = current->next;
	}
	last->next = new SourceEntry(constructor, check);
}

ISource *SourceEntry::Create()
{
	if (this->constructor != NULL)
		return (this->constructor)();
	return NULL;
}

SourceBuilder::Registrer::Registrer(instantiateFunction constructor,
		validityFunction check)
{
	headSB.AppendEntry(constructor, check);
}

